// 记录 Promise 的三种状态
const PENDING = 'pending'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'

/**
 * 运行一个微队列任务
 * 把传递的函数放到微队列中
 * @param {Function} callback
 */
function runMicroTask(callback) {
    // 决断 node 环境
    if (process && process.nextTick) {
        process.nextTick(callback)
    } else if (MutationObserver) {
        const observer = new MutationObserver(callback)
    } else {
        setTimeout(callback, 0)
    }
}

/**
 * 判断一个数据是否是 Promise 对象
 * @param obj
 */
function isPromise(obj) {
    return !!(obj && typeof obj === 'object' && typeof obj.then === 'function')
}

class MyPromise {
    /**
     * 创建一个 Promise
     * @param {Funtion} executor 任务执行器,立即执行
     */
    constructor(executor) {
        this._state = PENDING // 状态
        this._value = undefined // 数据
        this._handlers = [] // 处理函数形成的队列

        try {
            executor(this._resolve.bind(this), this._reject.bind(this))
        } catch (error) {
            this._reject(error)
        }
    }

    /**
     * 向处理队列中添加一个函数
     * @param {Function} executor 添加的函数
     * @param {String} state 该函数什么状态下执行
     * @param {Function} resolve 让 then 函数返回的 Promise 成功
     * @param {Function} reject 让 then 函数返回的 Promise 失败
     * @private
     */
    _pushHandler(executor, state, resolve, reject) {
        this._handlers.push({executor, state, resolve, reject})
    }

    /**
     * 根据实际情况,执行队列
     * @private
     */
    _runHandlers() {
        if (this._state === PENDING) {
            // 目前任务仍在挂起
            return
        }
        while (this._handlers[0]) {
            const handler = this._handlers[0]
            this._runOneHandler(handler)
            this._handlers.shift()
        }
    }

    /**
     * 处理一个 handler
     * @param {Object} handler
     * @private
     */
    _runOneHandler({executor, state, resolve, reject}) {
        runMicroTask(() => {
            // 状态不一致
            if (this._state !== state) return

            if (typeof executor !== 'function') {
                // 传递后续处理并非一个函数
                this._state === FULFILLED ? resolve(this._value) : reject(this._value)
            }

            try {
                const result = executor(this._value)
                if (isPromise(result)) {
                    return result.then(resolve, reject)
                } else {
                    resolve(result)
                }
            } catch (error) {
                reject(error)
            }

        })
    }

    /**
     * Promise A+ 规范的 then
     * @param {Function} onFulfilled
     * @param {Function} onRejected
     */
    then(onFulfilled, onRejected) {
        return new MyPromise((resolve, rejected) => {
            this._pushHandler(onFulfilled, FULFILLED, resolve, rejected)
            this._pushHandler(onRejected, REJECTED, resolve, rejected)
            this._runHandlers()
        })
    }

    /**
     * 更改任务状态
     * @param {String} newState 新状态
     * @param {any} value 相关数据
     * @private
     */
    _changeState(newState, value) {
        if (this._state !== PENDING) return
        this._state = newState
        this._value = value
        this._runHandlers() // 状态变化,执行队列
    }

    /**
     *  标记当前任务完成
     *  @param {any} data 任务完成的相关数据
     * @private
     */
    _resolve(data) {
        // 改变状态和数据
        this._changeState(FULFILLED, data)
    }

    /**
     * 标记当前任务失败
     * @param {any} reason  任务失败的相关数据
     * @private
     */
    _reject(reason) {
        // 改变状态和数据
        this._changeState(REJECTED, reason)
    }

}


const pro = new MyPromise((resolve, reject) => {
    setTimeout(() => {
        resolve(1)
    }, 1000)
})
const pro2 = pro.then((data) => {
    console.log(data)
    return new MyPromise((resolve,reject)=>{
       reject('a')
    })

})
setTimeout(() => {
    console.log(pro2)
}, 1500)